<template>
  <div class="app-container">
    <!-- 条件搜索 -->
    <div class="filter-container">
      <el-form ref="queryForm" :model="listQuery" size="small" :inline="true" label-width="auto">
        <el-form-item label="资源标题" prop="orgId">
          <treeselect
            v-model="listQuery.resId"
            style="width: 220px;"
            :options="resSelectOptions"
            :placeholder="'资源标题'"
            :normalizer="handleTreeSelectNormalizer"
            :multiple="false"
            :default-expand-level="1"
          />
        </el-form-item>
        <el-form-item label="使用状态" prop="status">
          <el-select v-model="listQuery.status" placeholder="使用状态" style="width: 150px;" class="filter-item" @change="handleFilterQuery">
            <el-option v-for="item in statusOptions" :key="item.code" :label="item.text" :value="item.code" />
          </el-select>
        </el-form-item>
        <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" style="margin-left: 10px;" @click="handleFilterQuery">
          搜索
        </el-button>
        <el-button v-waves class="filter-item" icon="el-icon-refresh-right" @click="handleRestQuery">
          重置
        </el-button>
      </el-form>
    </div>
    <div class="filter-container">
      <div style="float: left;">
        <el-button v-permission="permission.add" class="filter-item" type="primary" plain icon="el-icon-plus" @click="handleCreate">
          新增
        </el-button>
        <el-button class="filter-item" type="primary" plain icon="el-icon-sort" @click="handleExpand">
          展开/折叠
        </el-button>
      </div>
      <div style="float: right;">
        <el-button icon="el-icon-refresh" circle @click="handleFilterQuery" />
      </div>
    </div>

    <!-- 数据表格 -->
    <el-table
      ref="treeTable"
      :key="tableKey"
      v-loading="loading"
      row-key="resId"
      :data="list"
      border
      fit
      highlight-current-row
      style="width: 100%;"
      scrollbar-always-on="true"
      :default-expand-all="expandAll"
      :expand-row-keys="expandRowKeys"
      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
    >
      <!-- <el-table-column type="selection" width="50px" align="center" /> -->
      <el-table-column label="序号" type="index" width="50px" align="center" />
      <el-table-column label="资源标题" min-width="180px" align="left">
        <template v-slot="{row}">
          <span>{{ row.title }}</span>
        </template>
      </el-table-column>
      <el-table-column label="资源编码" min-width="120px" align="left">
        <template v-slot="{row}">
          <span>{{ row.name }}</span>
        </template>
      </el-table-column>
      <el-table-column label="资源类型" align="left" min-width="70px">
        <template v-slot="{row}">
          <el-tag v-if="row.type === 'D'" effect="dark">目录</el-tag>
          <el-tag v-else-if="row.type === 'M'" effect="dark" type="success">菜单</el-tag>
          <el-tag v-else effect="dark" type="warning">按钮</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="图标" min-width="60px" align="left">
        <template v-slot="{row}">
          <span v-if="!row.icon || row.icon === ''" />
          <span v-else-if="startWiths(row.icon, 'el-icon')" style="font-size:25px;"><i :class="row.icon" /></span>
          <span v-else style="font-size:20px;"><svg-icon :icon-class="row.icon" /></span>
        </template>
      </el-table-column>
      <el-table-column label="组件资源路径" min-width="140px" align="left">
        <template v-slot="{row}">
          <span>{{ row.component }}</span>
        </template>
      </el-table-column>
      <el-table-column label="权限标识" min-width="100px" align="left">
        <template v-slot="{row}">
          <span>{{ row.mid }}</span>
        </template>
      </el-table-column>
      <el-table-column label="是否显示" class-name="status-col" min-width="70px" align="left">
        <template v-slot="{row}">
          <el-tag v-if="row.isShow === 'N'" type="info">隐藏</el-tag>
          <el-tag v-else>显示</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="是否外链" class-name="status-col" min-width="70px" align="left">
        <template v-slot="{row}">
          <el-tag v-if="row.isFrame === 'Y'" type="info">是</el-tag>
          <el-tag v-else type="success">否</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="使用状态" class-name="status-col" width="70px">
        <template v-slot="{row}">
          <el-switch :value="row.status ==='Y'" disabled />
        </template>
      </el-table-column>
      <el-table-column label="更新人" min-width="70px" align="left">
        <template v-slot="{row}">
          <span>{{ row.updatedBy }}</span>
        </template>
      </el-table-column>
      <el-table-column label="更新时间" width="160px" align="left">
        <template v-slot="{row}">
          <span>{{ row.updatedTime | parseTime('{y}-{m}-{d} {h}:{i}:{s}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" fixed="right" width="160px" class-name="small-padding fixed-width">
        <template v-slot="{row,$index}">
          <el-button size="mini" type="info" icon="el-icon-document" @click="handleDetail(row, $index)">详情</el-button>
          <el-dropdown style="margin-left: 10px;" @command="handleClick($event, row, $index)">
            <el-button size="mini" type="primary">更多
              <i class="el-icon-arrow-down el-icon--right" />
            </el-button>
            <el-dropdown-menu>
              <el-dropdown-item v-permission="permission.edit" command="edit"><i class="el-icon-edit"> 编辑</i></el-dropdown-item>
              <el-dropdown-item v-permission="permission.del" command="del"><i class="el-icon-delete"> 删除</i></el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </template>
      </el-table-column>
    </el-table>

    <!-- 编辑页面 -->
    <el-dialog :title="title[state]" :visible.sync="visible" :close-on-click-modal="false" width="800px" @close="handleClose">
      <el-form ref="dataForm" :rules="rules" :model="formData" label-position="right" label-width="100px">
        <el-input v-model="formData.id" type="hidden" />
        <el-input v-model="formData.resId" type="hidden" />
        <el-row>
          <el-col :span="24">
            <el-form-item label="上级资源" prop="parentId">
              <treeselect
                v-model="formData.parentId"
                :options="resSelectOptions"
                :placeholder="'请选择'"
                :normalizer="handleTreeSelectNormalizer"
                :multiple="false"
                :default-expand-level="1"
                :disabled="state==='detail'"
                @input="handleMenuTreeSelectInput"
                @select="handleMenuTreeSelectChange"
                @deselect="handleMenuTreeSelectDeselect"
                @search-change="handleMenuTreeSelectSearch"
                @open="handleMenuTreeSelectOpen"
                @close="handleMenuTreeSelectClose"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="24">
            <el-form-item label="资源类型" prop="type">
              <el-radio-group v-model="formData.type" :disabled="state==='detail'" @change="handleTypeChange">
                <el-radio label="D">目录</el-radio>
                <el-radio label="M">菜单</el-radio>
                <el-radio label="B">按钮</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="12">
            <el-form-item label="资源标题" prop="title">
              <el-input v-model="formData.title" :readonly="state==='detail'" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="资源编码" prop="name">
              <el-input v-model="formData.name" :readonly="state==='detail'" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="12">
            <el-form-item label="资源排序" prop="seq">
              <el-input v-model.number="formData.seq" :readonly="state==='detail'" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="权限标识" prop="mid">
              <el-input v-model="formData.mid" :readonly="state==='detail'" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row v-if="formData.type === 'D' || formData.type === 'M'">
          <el-col :span="12">
            <el-form-item prop="isFrame">
              <span slot="label">
                <el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
                  <i class="el-icon-question" />
                </el-tooltip>
                是否外链
              </span>
              <el-radio-group v-model="formData.isFrame" :disabled="state==='detail'">
                <el-radio label="Y">是</el-radio>
                <el-radio label="N">否</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否显示" prop="isShow">
              <el-radio v-model="formData.isShow" :disabled="state==='detail'" label="Y">是</el-radio>
              <el-radio v-model="formData.isShow" :disabled="state==='detail'" label="N">否</el-radio>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row v-if="formData.type === 'D' || formData.type === 'M'">
          <el-col :span="12">
            <el-form-item prop="path">
              <span slot="label">
                <el-tooltip content="访问的路由地址，如链接的是外部地址则以`http(s)://`开头" placement="top">
                  <i class="el-icon-question" />
                </el-tooltip>
                路由地址
              </span>
              <el-input v-model="formData.path" :readonly="state==='detail'" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="图标" prop="icon">
              <el-popover
                placement="right"
                width="500"
                trigger="click"
              >
                <el-tabs type="border-card" class="icons-container">
                  <el-tab-pane label="Icons" style="height: 400px;">
                    <div class="icons-grid">
                      <div v-for="item of svgIcons" :key="item" @click="handleIcon(item, false)">
                        <el-tooltip placement="top">
                          <div slot="content">
                            {{ handleIconCode(item, false) }}
                          </div>
                          <div class="icon-item">
                            <svg-icon :icon-class="item" class-name="disabled" />
                            <span>{{ item }}</span>
                          </div>
                        </el-tooltip>
                      </div>
                    </div>
                  </el-tab-pane>
                  <el-tab-pane label="Element-UI Icons" style="height: 400px;">
                    <div class="icons-grid">
                      <div v-for="item of elementIcons" :key="item" @click="handleIcon(item, true)">
                        <el-tooltip placement="top">
                          <div slot="content">
                            {{ handleIconCode(item, true) }}
                          </div>
                          <div class="icon-item">
                            <i :class="'el-icon-' + item" />
                            <span>{{ item }}</span>
                          </div>
                        </el-tooltip>
                      </div>
                    </div>
                  </el-tab-pane>
                </el-tabs>
                <el-input slot="reference" v-model="formData.icon" :readonly="state==='detail'" placeholder="请输入" clearable>
                  <template v-if="!formData.icon || formData.icon === ''" v-slot:prepend />
                  <template v-else-if="startWiths(formData.icon, 'el-icon')" v-slot:prepend style="font-size:25px;"><i :class="formData.icon" /></template>
                  <template v-else v-slot:prepend style="font-size:20px;"><svg-icon :icon-class="formData.icon" /></template>
                </el-input>
              </el-popover>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row v-if="formData.type === 'D' || formData.type === 'M'">
          <el-col :span="24">
            <el-form-item prop="component">
              <span slot="label">
                <el-tooltip content="如果资源类型选择的是目录，则默认为`Layout`" placement="top">
                  <i class="el-icon-question" />
                </el-tooltip>
                组件路径
              </span>
              <el-input v-model="formData.component" :readonly="state==='detail'" placeholder="请输入" clearable>
                <template v-slot:prepend>@/views/</template>
              </el-input>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="12">
            <el-form-item label="使用状态" prop="status">
              <el-radio v-model="formData.status" :disabled="state==='detail'" label="Y">启用</el-radio>
              <el-radio v-model="formData.status" :disabled="state==='detail'" label="N">禁用</el-radio>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="24">
            <el-form-item label="备注">
              <el-input v-model="formData.remark" :disabled="state==='detail'" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="请输入" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button icon="el-icon-close" @click="handleClose">
          取消
        </el-button>
        <el-button v-if="state !=='detail'" :loading="submitting" type="primary" icon="el-icon-check" @click="handleSubmitFormData">
          <span v-if="!submitting">确认</span>
          <span v-else>提 交 中...</span>
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getPageList, handleSave, handleDelete, getAllResList } from './api'
import permission from '@/directive/permission/index' // 权限判断指令
// import checkPermission from '@/utils/permission' // 权限判断函数
import waves from '@/directive/waves' // waves directive
// import { parseTime, startWiths } from '@/utils'
import Treeselect from '@riophae/vue-treeselect'
import svgIcons from '../../icons/svg-icons'
import elementIcons from '../../icons/element-icons'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'

export default {
  name: 'ResInfo',
  components: { Treeselect },
  directives: { permission, waves },
  filters: {},
  data() {
    return {
      // 列表table的key
      tableKey: 0,
      // 遮罩层
      loading: true,
      // table数据对象
      list: [],
      // 是否展开TreeTable
      expandAll: false,
      // 展开节点
      expandRowKeys: [],
      // table条件查询对象
      listQuery: {
        resId: undefined,
        status: undefined
        // sort: '+id',
      },
      // 状态字典
      statusOptions: [{ code: 'Y', text: '启用' }, { code: 'N', text: '禁用' }],
      // 表单数据对象
      formData: {},
      // 树形菜单下拉选项
      resSelectOptions: [],
      // 是否显示弹出层
      visible: false,
      // 弹出层状态
      state: '',
      // 弹出层标题
      title: {
        update: '修改',
        create: '新增',
        detail: '详情'
      },
      // 权限标识
      permission: {
        add: ['sys:res:add'],
        edit: ['sys:res:edit'],
        del: ['sys:res:del']
      },
      submitting: false,
      // 表单校验规则
      rules: {
        parentId: [{ required: true, message: '上级资源不能为空', trigger: 'change' }],
        title: [{ required: true, message: '标题不能为空', trigger: 'change' }],
        name: [{ required: true, message: '编码不能为空', trigger: 'change' }],
        path: [{ required: true, message: '路由地址不能为空', trigger: 'change' }],
        component: [{ required: true, message: '组件路径不能为空', trigger: 'change' }],
        seq: [{ required: true, message: '排序号不能为空', trigger: 'change' }, { type: 'number', message: '序号必须为数字值' }]
      },
      svgIcons,
      elementIcons
    }
  },
  computed: {},
  watch: {},
  created() {
    // 列表table数据在页面渲染完成后加载
    this.handleInit()
    this.handleRestFormData()

    getAllResList({ type: 'B' }).then(res => {
      this.resSelectOptions = res.data
    })
  },
  mounted() {},
  methods: {
    // 查询table数据对象
    handleInit() {
      this.loading = true
      getPageList(this.listQuery).then(res => {
        this.list = res.data
        this.list.forEach(e => {
          if (e.type === 'D' || e.type === 'M') {
            this.expandRowKeys.push(e.resId)
          }
        })
        this.loading = false
      })
    },
    handleIconCode(symbol, isEl) {
      if (isEl) {
        return `<i class="el-icon-${symbol}" />`
      } else {
        return `<svg-icon icon-class="${symbol}" />`
      }
    },
    // 选中图标
    handleIcon(item, isEl) {
      if (isEl) {
        this.formData.icon = 'el-icon-' + item
      } else {
        this.formData.icon = item
      }
    },
    // 条件查询table数据
    handleFilterQuery() {
      this.listQuery.pageNum = 1
      this.handleInit()
    },
    // 重置table查询条件
    handleRestQuery() {
      this.$refs.queryForm.resetFields()
      this.handleInit()
    },
    // 重置表单
    handleRestFormData() {
      this.formData = {
        id: undefined,
        resId: undefined,
        parentId: undefined,
        name: undefined,
        type: 'D',
        seq: undefined,
        title: undefined,
        icon: undefined,
        path: undefined,
        component: 'Layout',
        mid: undefined,
        isFrame: 'N',
        isShow: 'Y',
        status: 'Y',
        remark: ''
      }
    },
    // 资源类型选择发生改变
    handleTypeChange(val) {
      if (val === 'D') {
        this.formData.component = 'Layout'
      } else {
        this.formData.component = undefined
      }
    },
    // 更多点击操作项
    handleClick(item, row, index) {
      // 编辑
      if (item === 'edit') {
        this.handleUpdate(row, index)
      }
      // 删除
      if (item === 'del') {
        this.handleDelete(row, index)
      }
    },
    // 新增
    handleCreate() {
      this.state = 'create'
      this.visible = true
      getAllResList({ type: 'B' }).then(res => {
        this.resSelectOptions = res.data
      })
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    // 修改
    handleUpdate(row) {
      if (row.parentId === 'root') {
        this.$message({
          showClose: true,
          message: '根目录资源不允许修改！',
          type: 'warning',
          duration: 4000
        })
        return
      }
      this.state = 'update'
      this.visible = true
      getAllResList({ type: 'B' }).then(res => {
        this.resSelectOptions = res.data
      })

      // 创建一个新的对象赋值
      this.formData = Object.assign({}, row)
      // 清理没有用的属性，避免数据不对问题
      delete this.formData.createdBy
      delete this.formData.createdTime
      delete this.formData.updatedBy
      delete this.formData.updatedTime
      delete this.formData.tenantId
      delete this.formData.revision
      delete this.formData.deleted

      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    // 详情
    handleDetail(row) {
      this.state = 'detail'
      this.visible = true
      getAllResList({ type: 'B' }).then(res => {
        this.resSelectOptions = res.data
      })

      // 创建一个新的对象赋值
      this.formData = Object.assign({}, row)

      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    // 删除
    handleDelete(row, index) {
      if (row.parentId === 'root') {
        this.$message({
          showClose: true,
          message: '根目录资源不允许删除！',
          type: 'warning',
          duration: 4000
        })
        return
      }
      this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 显示加载遮罩
        const loading = this.$loading({ lock: true, text: '处理中...', body: true, fullscreen: false, background: 'rgba(0, 0, 0, 0.05)' })
        handleDelete({ resId: row.resId }).then((res) => {
          loading.close()
          //  刷新table
          this.handleFilterQuery()
          this.$message({
            showClose: true,
            message: res.msg,
            type: 'success',
            duration: 4000
          })
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    // 表单提交
    handleSubmitFormData() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          this.submitting = true
          handleSave(this.formData).then((res) => {
            this.submitting = false
            //  刷新table
            this.handleFilterQuery()
            this.handleClose()
            this.$message({
              showClose: true,
              message: res.msg,
              type: 'success',
              duration: 4000
            })
          })
        }
      })
    },
    // 展开TreeTable
    handleExpand() {
      console.log(this.expandAll)
      this.expandAll = !this.expandAll
      console.log(this.expandAll)
      this.toggleRowExpansion_forAll(this.list, this.expandAll)
    },
    // 触发展开子节点
    toggleRowExpansion_forAll(data, isExpansion) {
      data.forEach(item => {
        this.$refs.treeTable.toggleRowExpansion(item, isExpansion)
        if (item.children !== undefined && item.children !== null) {
          this.toggleRowExpansion_forAll(item.children, isExpansion)
        }
      })
    },
    // 判断是否指定开头
    startWiths(str, startStr) {
      if (!str) {
        return false
      }
      return !!str.includes(startStr)
    },
    // 选中触发（第一次回显的时候会触发，清除值的时候会触发, value值为undefined） input事件用于v-model双向绑定组件更新父组件值
    handleMenuTreeSelectInput(value, instanceId) {
      // console.log(value, 'input事件')
      // console.log(this.value, 'this.value -- input') // 这个不需要 延迟
    },
    // 选中触发（清除值的时候不会触发）
    handleMenuTreeSelectChange(raw, instanceId) {
      // console.log(raw, '当前的对象')
      // setTimeout(() => { // 如果用到this.value 需要setTimeout延迟一下拿到最新的值
      //   console.log(this.value, 'this.value -- select')
      // })
    },
    // 移除选项时触发 当设置multiple为true时生效  raw为当前移除的对象
    handleMenuTreeSelectDeselect(raw, instanceId) {
      // console.log(raw, 'deselect-->>')
    },
    // 搜索
    handleMenuTreeSelectSearch(searchQuery, instanceId) {
      // console.log(searchQuery, '当前搜索的值')
    },
    // 展开触发
    handleMenuTreeSelectOpen(instanceId) {
      // console.log('展开了')
      // console.log(instanceId)
    },
    // 关闭触发
    handleMenuTreeSelectClose(value, instanceId) {
      // console.log(value, '当前的value值')
    },
    // 字段默认 id label 用于规范化数据源
    handleTreeSelectNormalizer(node) {
      if (!node.children || !node.children.length) {
        delete node.children
      }
      return node
    },
    // 关闭弹出层
    handleClose() {
      this.$refs['dataForm'].resetFields()
      this.handleRestFormData()
      this.visible = false
    }
  }
}
</script>

<style lang="scss" scoped>
.icons-container {
  margin: 0;
  //overflow: hidden;

  .icons-grid {
    height: 400px;
    overflow-y: scroll;
    position: relative;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
  }

  .icon-item {
    margin: 1px;
    height: 85px;
    text-align: center;
    width: 80px;
    float: left;
    font-size: 20px;
    color: #24292e;
    cursor: pointer;
  }

  span {
    display: block;
    font-size: 12px;
    //margin-top: 10px;
  }

  .disabled {
    pointer-events: none;
  }
}
.vue-treeselect{
  height: 32px !important;
}
.vue-treeselect__control{
   height: 32px !important;
}
div.vue-treeselect__control{
   height: 32px !important;
}
input.vue-treeselect__input{
  height: 32px !important;
}
.vue-treeselect__input-container{
  height: 32px !important;
}
.vue-treeselect__placeholder,
.vue-treeselect__single-value {
  line-height: 32px !important;
}
.el-input.is-disabled .el-input__inner {
  background-color: #ffffff !important;
  cursor: pointer !important;
}
.el-radio.is-disabled .el-radio__inner {
  background-color: #ffffff !important;
  cursor: pointer !important;
}
.el-radio__input.is-disabled {
  background-color: #ffffff !important;
  cursor: pointer !important;
}
.el-radio__input.is-disabled.is-checked {
  background-color: #ffffff !important;
  cursor: pointer !important;
}
.el-radio__label {
  background-color: #ffffff !important;
  cursor: pointer !important;
}
.el-textarea.is-disabled .el-textarea__inner {
  background-color: #ffffff !important;
}
.vue-treeselect--disabled .vue-treeselect__control {
  background-color: #ffffff !important;
}
</style>
